// run.C
//
// Template run macro for AliBasicTask.cxx/.h with example layout of
// physics selections and options, in macro and task.
//
// Author: Arvinder Palaha
//
class AliAnalysisGrid;

//______________________________________________________________________________
void run(
        const char* runtype = "proof", // local, proof or grid
        const char *gridmode = "full", // Set the run mode (can be "full", "test", "offline", "submit" or "terminate"). Full & Test work for proof
        const bool bMCtruth = 0, // 1 = MCEvent handler is on (MC truth), 0 = MCEvent handler is off (MC reconstructed/real data)
        const bool bMCphyssel = 0, // 1 = looking at MC truth or reconstructed, 0 = looking at real data
        const bool SystFlag = 0,  // 1 = running all tasks for systematics analysis, 0 = running only standard cuts
        const Long64_t nentries = 1234567890, // for local and proof mode, ignored in grid mode. Set to 1234567890 for all events.
        const Long64_t firstentry = 0, // for local and proof mode, ignored in grid mode
        const char *proofdataset = "/alice/data/LHC10e_000130517_p2",

        //path to dataset on proof cluster, for proof analysis
        //see for info
        //root[]TProof::Open("skaf.saske.sk")
        //root[]gProof->ShowDataSets()
        //and look at http://alimonitor.cern.ch/configuration/
        //
        //Good datasets on cluster "skaf.saske.sk":
        //"/alice/data/LHC10h_000138275_p2", PbPb at 2760 GeV, 3,280,000 events
        //"/alice/data/LHC10h_000137366_p2", PbPb at 2760 GeV, 1,270,000 events

        //"/alice/data/LHC10e_000130517_p2",  pp  at  7 TeV, 5,809,071

        //"/alice/sim/LHC10d1_000117109"

        // caf: /alice/sim/LHC10e20_000130844|/alice/sim/LHC10e20_000130520|/default/kimb/sim_LHC10e20_000130158_ESDs|/alice/sim/LHC10e20_000128913

        const char *proofcluster = "alice-caf.cern.ch",

        //"skaf.saske.sk",
        //"alice-caf.cern.ch"
        //"kiaf.sdfarm.kr"
        // which proof cluster to use in proof mode

        const char *taskname = "Phi16x16_NewCorrectionsTest_1907"
        // sets name of grid generated macros
        )
{
    gEnv->SetValue("XSec.GSI.DelegProxy", "2");
    // check run type
    if(runtype != "local" && runtype != "proof" && runtype != "grid"){
        Printf("\n\tIncorrect run option, check first argument of run macro");
        Printf("\tint runtype = local, proof or grid\n");
        return;
    }
    Printf("%s analysis chosen",runtype);


    // load libraries
    gSystem->Load("libCore.so");
    gSystem->Load("libGeom.so");
    gSystem->Load("libVMC.so");
    gSystem->Load("libPhysics.so");
    gSystem->Load("libTree.so");
    gSystem->Load("libSTEERBase.so");
    gSystem->Load("libESD.so");
    gSystem->Load("libAOD.so");
    gSystem->Load("libANALYSIS.so");
    gSystem->Load("libANALYSISalice.so");

    // add aliroot indlude path
    gROOT->ProcessLine(Form(".include %s/include",gSystem->ExpandPathName("$ALICE_ROOT")));
    gROOT->SetStyle("Plain");

    // analysis manager
    AliAnalysisManager* mgr = new AliAnalysisManager(taskname);
    
    // create the alien handler and attach it to the manager
    AliAnalysisGrid *plugin = CreateAlienHandler(taskname, gridmode, proofcluster, proofdataset,bMCtruth,bMCphyssel);
    mgr->SetGridHandler(plugin);
    
    AliVEventHandler* esdH = new AliESDInputHandler();
    mgr->SetInputEventHandler(esdH);

    // mc event handler
    if(bMCtruth) {
        AliMCEventHandler* mchandler = new AliMCEventHandler();
        // Not reading track references
        mchandler->SetReadTR(kFALSE);
        mgr->SetMCtruthEventHandler(mchandler);
    }

    // === Physics Selection Task ===
    //
    // In SelectCollisionCandidate(), default is kMB, so the task UserExec()
    // function is only called for these events.
    // Options are:
    //    kMB             Minimum Bias trigger
    //    kMBNoTRD        Minimum bias trigger where the TRD is not read out
    //    kMUON           Muon trigger
    //    kHighMult       High-Multiplicity Trigger
    //    kUserDefined    For manually defined trigger selection
    //
    // Multiple options possible with the standard AND/OR operators && and ||
    // These all have the usual offline SPD or V0 selections performed.
    //
    // With a pointer to the physics selection object using physSelTask->GetPhysicsSelection(),
    // one can manually set the selected and background classes using:
    //    AddCollisionTriggerClass("+CINT1B-ABCE-NOPF-ALL")
    //    AddBGTriggerClass("+CINT1A-ABCE-NOPF-ALL");
    //
    // One can also specify multiple classes at once, or require a class to NOT
    // trigger, for e.g.
    //    AddBGTriggerClass("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL");
    //
    // NOTE that manually setting the physics selection overrides the standard
    // selection, so it must be done in completeness.
    //
    // ALTERNATIVELY, one can make the physics selection inside the task
    // UserExec().
    // For this case, comment out the task->SelectCol.... line,
    // and see AliBasicTask.cxx UserExec() function for details on this.


    gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
    AliPhysicsSelectionTask *physSelTask = AddTaskPhysicsSelection(bMCphyssel);
    if(!physSelTask) { Printf("no physSelTask"); return; }
    //AliPhysicsSelection *physSel = physSelTask->GetPhysicsSelection();
    //physSel->AddCollisionTriggerClass("+CINT1B-ABCE-NOPF-ALL");// #3119 #769");



    //create taskCentrality (for AA)

    /*void configureTaskOutput (AliAnalysisTask* taskAnalysis, TString strPrefixName= "")
{
    if(!taskAnalysis)
    return;
    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr)
    {
    Error("configureTaskOutput", "No analysis manager to connect to.");
    return ;
    }

    if (!mgr->GetInputEventHandler())
    {
    Error("AddTaskAnalysis", "This task requires an input event handler");
    return ;
    }

}*/

    /*gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
    AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
    //taskCentrality->SetPass(2); // remember to set the pass you are processing!!!
    configureTaskOutput( taskCentrality, "taskCentrality");*/
    

    //track cuts for ESD analysis
    AliESDtrackCuts *AnchorCuts = new AliESDtrackCuts("Cuts","Cuts");
    AnchorCuts->SetMinNClustersTPC(80);
    AnchorCuts->SetMinNClustersITS(2);
    AnchorCuts->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
    AnchorCuts->SetRequireTPCRefit(kTRUE);
    AnchorCuts->SetRequireITSRefit(kTRUE);
    AnchorCuts->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
    AnchorCuts->SetMaxDCAToVertexXY(0.5);
    AnchorCuts->SetMaxDCAToVertexZ(0.5);
    AnchorCuts->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
    AnchorCuts->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop
    //cuts->SaveHistograms("fTrackCuts");


    //be careful with N of Eta Configs! See the table below (EtaSizeInBins, EtaStepInBins, NofEtaBins - N of Eta Configs with/without overlapping); [] - not used actually
    // 16, 2, 2, - 8 or 7
    // 32, 4, 2 - 15 or [12]
    // 16, 4, 2 - [7] or 5
    // 16, 6, 2 - [6] or 3
    // 16, 8, 0 - [5] or 1
    // 1,  1, 0 - for future Phi separated windows only
    //it is also possible to include in the future the position of center, bool shift, bool overlapping, etc...


    // create tasks

    gROOT->LoadMacro("AliAnalysisTaskPhi.cxx++g");
    AliAnalysisTaskPhi* taskPhiMain = new AliAnalysisTaskPhi(taskname);
    taskPhiMain->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
    taskPhiMain->SetTrackCuts(AnchorCuts);
    taskPhiMain->SetVtxDiamond(0.4, 0.4, 7.0);
    taskPhiMain->SetPhiConfiguration(8, 16); // NumberOfSectors, NumberOfPhiSteps; define SectorSize = 2*TMath::Pi()/fNSectors and PhiStep = 2*TMath::Pi()/fNPhiSteps;
    taskPhiMain->SetEtaConfiguration(32, 4, 2, 15); //N of Eta bins in Event hist, EtaSizeInBins, EtaStepInBins, N of Eta configs

    taskPhiMain->SetPtMin(0.3);
    taskPhiMain->SetPtMax(1.5);
    taskPhiMain->SetMinMult(0);



    // create additional tasks
    if(SystFlag)
    {
        // |Vertex Z position| < 3 cm_____________________________________________________________________
        AliAnalysisTaskPhi* taskVtx3 = new AliAnalysisTaskPhi(taskname);
        taskVtx3->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
        taskVtx3->SetTrackCuts(AnchorCuts);
        taskVtx3->SetVtxDiamond(0.4, 0.4, 3.0);
        taskVtx3->SetNumberOfSectors(8);
        taskVtx3->SetPtMin(0.3);
        taskVtx3->SetPtMax(1.5);
        taskVtx3->SetMinMult(0);

        // |Vertex Z position| < 5 cm_______________________________________________________________________
        AliAnalysisTaskPhi* taskVtx5 = new AliAnalysisTaskPhi(taskname);
        taskVtx5->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
        taskVtx5->SetTrackCuts(AnchorCuts);
        taskVtx5->SetVtxDiamond(0.4, 0.4, 5.0);
        taskVtx5->SetNumberOfSectors(8);
        taskVtx5->SetPtMin(0.3);
        taskVtx5->SetPtMax(1.5);
        taskVtx5->SetMinMult(0);

        // |Vertex Z position| < 10 cm_____________________________________________________________________
        AliAnalysisTaskPhi* taskVtx10 = new AliAnalysisTaskPhi(taskname);
        taskVtx10->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
        taskVtx10->SetTrackCuts(AnchorCuts);
        taskVtx10->SetVtxDiamond(0.4, 0.4, 10.0);
        taskVtx10->SetNumberOfSectors(8);
        taskVtx10->SetPtMin(0.3);
        taskVtx10->SetPtMax(1.5);
        taskVtx10->SetMinMult(0);

        //N of TPC clusters 40________________________________________________________________________
        AliAnalysisTaskPhi* taskTPC40 = new AliAnalysisTaskPhi(taskname);
        taskTPC40->SelectCollisionCandidates(AliVEvent::kMB);

        AliESDtrackCuts *cutsTPC40 = new AliESDtrackCuts("CutsTPC40","CutsTPC40");
        cutsTPC40->SetMinNClustersTPC(40);
        cutsTPC40->SetMinNClustersITS(2);
        cutsTPC40->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
        cutsTPC40->SetRequireTPCRefit(kTRUE);
        cutsTPC40->SetRequireITSRefit(kTRUE);
        cutsTPC40->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
        cutsTPC40->SetMaxDCAToVertexXY(0.5);
        cutsTPC40->SetMaxDCAToVertexZ(0.5);
        cutsTPC40->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
        cutsTPC40->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

        taskTPC40->SetTrackCuts(cutsTPC40);
        taskTPC40->SetVtxDiamond(0.4, 0.4, 7.0);
        taskTPC40->SetNumberOfSectors(8);
        taskTPC40->SetPtMin(0.3);
        taskTPC40->SetPtMax(1.5);
        taskTPC40->SetMinMult(0);

        //N of TPC clusters 100________________________________________________________________________
        AliAnalysisTaskPhi* taskTPC100 = new AliAnalysisTaskPhi(taskname);
        taskTPC100->SelectCollisionCandidates(AliVEvent::kMB);

        AliESDtrackCuts *cutsTPC100 = new AliESDtrackCuts("CutsTPC100","CutsTPC100");
        cutsTPC100->SetMinNClustersTPC(100);
        cutsTPC100->SetMinNClustersITS(2);
        cutsTPC100->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
        cutsTPC100->SetRequireTPCRefit(kTRUE);
        cutsTPC100->SetRequireITSRefit(kTRUE);
        cutsTPC100->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
        cutsTPC100->SetMaxDCAToVertexXY(0.5);
        cutsTPC100->SetMaxDCAToVertexZ(0.5);
        cutsTPC100->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
        cutsTPC100->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

        taskTPC100->SetTrackCuts(cutsTPC100);
        taskTPC100->SetVtxDiamond(0.4, 0.4, 7.0);
        taskTPC100->SetNumberOfSectors(8);
        taskTPC100->SetPtMin(0.3);
        taskTPC100->SetPtMax(1.5);
        taskTPC100->SetMinMult(0);

        //N of ITS clusters 0_________________________________________________________________________
        AliAnalysisTaskPhi* taskITS0 = new AliAnalysisTaskPhi(taskname);
        taskITS0->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

        AliESDtrackCuts *cutsITS0 = new AliESDtrackCuts("CutsITS0","CutsITS0");
        cutsITS0->SetMinNClustersTPC(80);
        cutsITS0->SetMinNClustersITS(0);
        cutsITS0->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
        cutsITS0->SetRequireTPCRefit(kTRUE);
        cutsITS0->SetRequireITSRefit(kTRUE);
        cutsITS0->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
        cutsITS0->SetMaxDCAToVertexXY(0.5);
        cutsITS0->SetMaxDCAToVertexZ(0.5);
        cutsITS0->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
        cutsITS0->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

        taskITS0->SetTrackCuts(cutsITS0);
        taskITS0->SetVtxDiamond(0.4, 0.4, 7.0);
        taskITS0->SetNumberOfSectors(8);
        taskITS0->SetPtMin(0.3);
        taskITS0->SetPtMax(1.5);
        taskITS0->SetMinMult(0);

        //N of ITS clusters 4_________________________________________________________________________
        AliAnalysisTaskPhi* taskITS4 = new AliAnalysisTaskPhi(taskname);
        taskITS4->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

        AliESDtrackCuts *cutsITS4 = new AliESDtrackCuts("CutsITS4","CutsITS4");
        cutsITS4->SetMinNClustersTPC(80);
        cutsITS4->SetMinNClustersITS(4);
        cutsITS4->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
        cutsITS4->SetRequireTPCRefit(kTRUE);
        cutsITS4->SetRequireITSRefit(kTRUE);
        cutsITS4->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
        cutsITS4->SetMaxDCAToVertexXY(0.5);
        cutsITS4->SetMaxDCAToVertexZ(0.5);
        cutsITS4->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
        cutsITS4->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

        taskITS4->SetTrackCuts(cutsITS4);
        taskITS4->SetVtxDiamond(0.4, 0.4, 7.0);
        taskITS4->SetNumberOfSectors(8);
        taskITS4->SetPtMin(0.3);
        taskITS4->SetPtMax(1.5);
        taskITS4->SetMinMult(0);

        //DCA to vetrex 0.1_________________________________________________________________________
        AliAnalysisTaskPhi* taskDCA01 = new AliAnalysisTaskPhi(taskname);
        taskDCA01->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

        AliESDtrackCuts *cutsDCA01 = new AliESDtrackCuts("CutsDCA01","CutsDCA01");
        cutsDCA01->SetMinNClustersTPC(80);
        cutsDCA01->SetMinNClustersITS(2);
        cutsDCA01->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
        cutsDCA01->SetRequireTPCRefit(kTRUE);
        cutsDCA01->SetRequireITSRefit(kTRUE);
        cutsDCA01->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
        cutsDCA01->SetMaxDCAToVertexXY(0.1);
        cutsDCA01->SetMaxDCAToVertexZ(0.1);
        cutsDCA01->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
        cutsDCA01->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

        taskDCA01->SetTrackCuts(cutsDCA01);
        taskDCA01->SetVtxDiamond(0.4, 0.4, 7.0);
        taskDCA01->SetNumberOfSectors(8);
        taskDCA01->SetPtMin(0.3);
        taskDCA01->SetPtMax(1.5);
        taskDCA01->SetMinMult(0);

        //DCA to vetrex 2.0_________________________________________________________________________
        AliAnalysisTaskPhi* taskDCA20 = new AliAnalysisTaskPhi(taskname);
        taskDCA20->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

        AliESDtrackCuts *cutsDCA20 = new AliESDtrackCuts("CutsDCA01","CutsDCA01");
        cutsDCA20->SetMinNClustersTPC(80);
        cutsDCA20->SetMinNClustersITS(2);
        cutsDCA20->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
        cutsDCA20->SetRequireTPCRefit(kTRUE);
        cutsDCA20->SetRequireITSRefit(kTRUE);
        cutsDCA20->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
        cutsDCA20->SetMaxDCAToVertexXY(2.0);
        cutsDCA20->SetMaxDCAToVertexZ(2.0);
        cutsDCA20->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
        cutsDCA20->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

        taskDCA20->SetTrackCuts(cutsDCA20);
        taskDCA20->SetVtxDiamond(0.4, 0.4, 7.0);
        taskDCA20->SetNumberOfSectors(8);
        taskDCA20->SetPtMin(0.3);
        taskDCA20->SetPtMax(1.5);
        taskDCA20->SetMinMult(0);

        //ITS TPC refit kFalse________________________________________________________________________
        AliAnalysisTaskPhi* taskRefitFalse = new AliAnalysisTaskPhi(taskname);
        taskRefitFalse->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented

        AliESDtrackCuts *cutsRefitFalse = new AliESDtrackCuts("CutsRefitFalse","CutsRefitFalse");
        cutsRefitFalse->SetMinNClustersTPC(80);
        cutsRefitFalse->SetMinNClustersITS(2);
        cutsRefitFalse->SetMaxChi2PerClusterTPC(4.0); //max value of chi^2/N for track
        cutsRefitFalse->SetRequireTPCRefit(kFALSE);
        cutsRefitFalse->SetRequireITSRefit(kFALSE);
        cutsRefitFalse->SetAcceptKinkDaughters(kFALSE); //tracks from reconstructed secondary vertexes
        cutsRefitFalse->SetMaxDCAToVertexXY(0.5);
        cutsRefitFalse->SetMaxDCAToVertexZ(0.5);
        cutsRefitFalse->SetPtRange(0.1,100); //Pt selection is also performed in ESD track loop
        cutsRefitFalse->SetEtaRange(-1.8,1.8); //Eta selection is also performed in ESD track loop

        taskRefitFalse->SetTrackCuts(cutsRefitFalse);
        taskRefitFalse->SetVtxDiamond(0.4, 0.4, 7.0);
        taskRefitFalse->SetNumberOfSectors(8);
        taskRefitFalse->SetPtMin(0.3);
        taskRefitFalse->SetPtMax(1.5);
        taskRefitFalse->SetMinMult(0);

        //TPC only track cuts____________________________________________________________________________
        AliAnalysisTaskPhi* taskTPConly = new AliAnalysisTaskPhi(taskname);
        taskTPConly->SelectCollisionCandidates(AliVEvent::kMB);
        taskTPConly->SetTrackCuts(AliESDtrackCuts::GetStandardTPCOnlyTrackCuts() );
        taskTPConly->SetVtxDiamond(0.4, 0.4, 7.0);
        taskTPConly->SetNumberOfSectors(8);
        taskTPConly->SetPtMin(0.3);
        taskTPConly->SetPtMax(1.5);
        taskTPConly->SetMinMult(0);

        //Standard ITS TPC track cuts kTRUE______________________________________________________________
        AliAnalysisTaskPhi* taskITSTPC = new AliAnalysisTaskPhi(taskname);
        taskITSTPC->SelectCollisionCandidates(AliVEvent::kMB);
        taskITSTPC->SetTrackCuts(AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE));
        taskITSTPC->SetVtxDiamond(0.4, 0.4, 7.0);
        taskITSTPC->SetNumberOfSectors(8);
        taskITSTPC->SetPtMin(0.3);
        taskITSTPC->SetPtMax(1.5);
        taskITSTPC->SetMinMult(0);

        //Standard ITS TPC track cuts kFALSE______________________________________________________________
        AliAnalysisTaskPhi* taskITSTPCfalse = new AliAnalysisTaskPhi(taskname);
        taskITSTPCfalse->SelectCollisionCandidates(AliVEvent::kMB);
        taskITSTPCfalse->SetTrackCuts(AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kFALSE));
        taskITSTPCfalse->SetVtxDiamond(0.4, 0.4, 7.0);
        taskITSTPCfalse->SetNumberOfSectors(8);
        taskITSTPCfalse->SetPtMin(0.3);
        taskITSTPCfalse->SetPtMax(1.5);
        taskITSTPCfalse->SetMinMult(0);

        //Standard ITS TPC track cuts kTRUE with Crossed Rows_____________________________________________
        AliAnalysisTaskPhi* taskITSTPCCrossedRows = new AliAnalysisTaskPhi(taskname);
        taskITSTPCCrossedRows->SelectCollisionCandidates(AliVEvent::kMB);
        taskITSTPCCrossedRows->SetTrackCuts(AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE,1));
        taskITSTPCCrossedRows->SetVtxDiamond(0.4, 0.4, 7.0);
        taskITSTPCCrossedRows->SetNumberOfSectors(8);
        taskITSTPCCrossedRows->SetPtMin(0.3);
        taskITSTPCCrossedRows->SetPtMax(1.5);
        taskITSTPCCrossedRows->SetMinMult(0);

        mgr->AddTask(taskVtx3);
        mgr->AddTask(taskVtx5);
        mgr->AddTask(taskVtx10);
        mgr->AddTask(taskTPC40);
        mgr->AddTask(taskTPC100);
        mgr->AddTask(taskITS0);
        mgr->AddTask(taskITS4);
        mgr->AddTask(taskDCA01);
        mgr->AddTask(taskDCA20);
        mgr->AddTask(taskRefitFalse);
        mgr->AddTask(taskTPConly);
        mgr->AddTask(taskITSTPC);
        mgr->AddTask(taskITSTPCfalse);
        mgr->AddTask(taskITSTPCCrossedRows);
    }

    mgr->AddTask(taskPhiMain);


    if (bMCtruth)
    {
        //create task MCtrue
        gROOT->LoadMacro("AliAnalysisTaskMCtruePhi.cxx++g");
        AliAnalysisTaskMCtruePhi* taskMCtrue = new AliAnalysisTaskMCtruePhi(taskname);

        taskMCtrue->SelectCollisionCandidates(AliVEvent::kMB); // if physics selection performed in UserExec(), this line should be commented
        taskMCtrue->SetVtxDiamond(0.4, 0.4, 7.0);

        taskMCtrue->SetPhiConfiguration(8, 16); // NumberOfSectors, NumberOfPhiSteps; define SectorSize = 2*TMath::Pi()/fNSectors and PhiStep = 2*TMath::Pi()/fNPhiSteps;
        taskMCtrue->SetEtaConfiguration(32, 4, 2, 15); //N of Eta bins in Event hist, EtaSizeInBins, EtaStepInBins, N of Eta configs

        taskMCtrue->SetPtMin(0.3);
        taskMCtrue->SetPtMax(1.5);
        taskMCtrue->SetMinMult(0);
        mgr->AddTask(taskMCtrue);
    }

    // set output root file name for different analysis
    TString outfilename = Form("list.%s.root",runtype);

    // create containers for input/output
    AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
    AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("outputPhi256", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);


    if(SystFlag)
    {
        AliAnalysisDataContainer *coutputVtx3 = mgr->CreateContainer("Vertex3", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputVtx5 = mgr->CreateContainer("Vertex5", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputVtx10 = mgr->CreateContainer("Vertex10", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputTPC40 = mgr->CreateContainer("TPC40", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputTPC100 = mgr->CreateContainer("TPC100", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputITS0 = mgr->CreateContainer("ITS0", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputITS4 = mgr->CreateContainer("ITS4", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputDCA01 = mgr->CreateContainer("DCA01", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputDCA20 = mgr->CreateContainer("DCA20", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputRefitFalse = mgr->CreateContainer("ITSTPCRefitFalse", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputTPConly = mgr->CreateContainer("TPConly", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputITSTPC = mgr->CreateContainer("StandardITSTPC", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputITSTPCfalse = mgr->CreateContainer("StandardITSTPCfalse", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
        AliAnalysisDataContainer *coutputITSTPCCrossedRows = mgr->CreateContainer("StandardITSTPCCrossedRows", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    }

    if (bMCtruth)
    {
        AliAnalysisDataContainer *MCtrueOutput = mgr->CreateContainer("MCtrueOutputPhi256", TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);
    }


    // connect input/output for tasks
    mgr->ConnectInput(taskPhiMain, 0, cinput);
    mgr->ConnectOutput(taskPhiMain, 1, coutput1);


    if (SystFlag)
    {
        mgr->ConnectInput(taskVtx3, 0, cinput);
        mgr->ConnectOutput(taskVtx3, 1, coutputVtx3);

        mgr->ConnectInput(taskVtx5, 0, cinput);
        mgr->ConnectOutput(taskVtx5, 1, coutputVtx5);

        mgr->ConnectInput(taskVtx10, 0, cinput);
        mgr->ConnectOutput(taskVtx10, 1, coutputVtx10);

        mgr->ConnectInput(taskTPC40, 0, cinput);
        mgr->ConnectOutput(taskTPC40, 1, coutputTPC40);

        mgr->ConnectInput(taskTPC100, 0, cinput);
        mgr->ConnectOutput(taskTPC100, 1, coutputTPC100);

        mgr->ConnectInput(taskITS0, 0, cinput);
        mgr->ConnectOutput(taskITS0, 1, coutputITS0);

        mgr->ConnectInput(taskITS4, 0, cinput);
        mgr->ConnectOutput(taskITS4, 1, coutputITS4);

        mgr->ConnectInput(taskDCA01, 0, cinput);
        mgr->ConnectOutput(taskDCA01, 1, coutputDCA01);

        mgr->ConnectInput(taskDCA20, 0, cinput);
        mgr->ConnectOutput(taskDCA20, 1, coutputDCA20);

        mgr->ConnectInput(taskRefitFalse, 0, cinput);
        mgr->ConnectOutput(taskRefitFalse, 1, coutputRefitFalse);

        mgr->ConnectInput(taskTPConly, 0, cinput);
        mgr->ConnectOutput(taskTPConly, 1, coutputTPConly);

        mgr->ConnectInput(taskITSTPC, 0, cinput);
        mgr->ConnectOutput(taskITSTPC, 1, coutputITSTPC);

        mgr->ConnectInput(taskITSTPCfalse, 0, cinput);
        mgr->ConnectOutput(taskITSTPCfalse, 1, coutputITSTPCfalse);

        mgr->ConnectInput(taskITSTPCCrossedRows, 0, cinput);
        mgr->ConnectOutput(taskITSTPCCrossedRows, 1, coutputITSTPCCrossedRows);
    }


    if (bMCtruth)
    {
        mgr->ConnectInput(taskMCtrue, 0, cinput);
        mgr->ConnectOutput(taskMCtrue, 1, MCtrueOutput);
    }

    // enable debug printouts
    mgr->SetDebugLevel(2);
    if (!mgr->InitAnalysis()) return;
    mgr->PrintStatus();

    // start analysis
    Printf("Starting Analysis....");
    mgr->StartAnalysis(runtype,nentries,firstentry);
}

//______________________________________________________________________________
AliAnalysisGrid* CreateAlienHandler(const char *taskname, const char *gridmode, const char *proofcluster, const char *proofdataset, bool bMCtruth, bool bMCphyssel)
{
    AliAnalysisAlien *plugin = new AliAnalysisAlien();
    // Set the run mode (can be "full", "test", "offline", "submit" or "terminate")
    plugin->SetRunMode(gridmode);

    // Set versions of used packages
    plugin->SetAPIVersion("V1.1x");
    plugin->SetROOTVersion("v5-34-05");

    plugin->SetAliROOTVersion("v5-04-67-AN");
    //plugin->SetRootVersionForProof( "VO_ALICE@ROOT::v5-34-02" );

    // Declare input data to be processed.

    // Method 1: Create automatically XML collections using alien 'find' command.
    // Define production directory LFN
    if ( !bMCtruth && !bMCphyssel ) //working with real data sets
    {

        //pp 7 TeV

        plugin->SetGridDataDir("/alice/data/2010/LHC10d");

        // Set data search pattern
        //plugin->SetDataPattern("*ESDs.root"); // THIS CHOOSES ALL PASSES
        plugin->SetDataPattern("*ESDs/pass2/*ESDs.root"); // CHECK LATEST PASS OF DATA SET IN ALIENSH!!!

        plugin->SetRunPrefix("000");
        // ...then add run numbers to be considered
        plugin->AddRunNumber(126078);
        plugin->AddRunNumber(126082);
        plugin->AddRunNumber(126088);
        plugin->AddRunNumber(126090);
        plugin->AddRunNumber(126158);
        plugin->AddRunNumber(126007);

        // additional LHC10d runs if needed:
        //        125842
        //        125849
        //        125850
        //        125855
        //        126073


        //        old LHC10e runs:
        //plugin->SetGridDataDir("/alice/data/2010/LHC10e");

        //        plugin->AddRunNumber(130704);
        //        plugin->AddRunNumber(130793);
        //        plugin->AddRunNumber(130517);
        //        plugin->AddRunNumber(130795);
    }
    else
    {
        //working with MC data

        //pp 7 TeV

        //plugin->SetGridDataDir("/alice/sim/LHC10f6");  //Phojet LHC10d anchor
        plugin->SetGridDataDir("/alice/sim/LHC10f6a"); //Pythia Perugia0 LHC10d anchor
        plugin->SetDataPattern("*ESDs.root");

        // ...then add run numbers to be considered (limited by the grid jobs quota!)
        //part1
//        plugin->AddRunNumber(126078);
//        plugin->AddRunNumber(126082);
//        plugin->AddRunNumber(126007);

        //part2
        plugin->AddRunNumber(126088);
        plugin->AddRunNumber(126090);
        plugin->AddRunNumber(126158);


        //old LHC10e anchor runs
        //plugin->SetGridDataDir("/alice/sim/LHC10e20");
        // LHC10e20 runs (LHC10e anchor):
        //        plugin->AddRunNumber(130704);
        //        plugin->AddRunNumber(130793);
        //        plugin->AddRunNumber(130517);
        //        plugin->AddRunNumber(130795);
        //        plugin->AddRunNumber(130848);
        //        plugin->AddRunNumber(130375);
        //        plugin->AddRunNumber(130844);
        //        plugin->AddRunNumber(130519);
        //        plugin->AddRunNumber(130178);
        //        plugin->AddRunNumber(130149);
        //        plugin->AddRunNumber(129961);
        //        plugin->AddRunNumber(129735);
        //        plugin->AddRunNumber(129736);
        //        plugin->AddRunNumber(129667);
        //        plugin->AddRunNumber(129654);


    }


    plugin->SetNrunsPerMaster(1);
    plugin->SetOutputToRunNo();
    // comment out the next line when using the "terminate" option, unless
    // you want separate merged files for each run

    //MergeOutputs: ### Re-run with <MergeViaJDL> off to collect results after merging jobs are done ###
    plugin->SetMergeViaJDL();

    // Method 2: Declare existing data files (raw collections, xml collections, root file)
    // If no path mentioned data is supposed to be in the work directory (see SetGridWorkingDir())
    // XML collections added via this method can be combined with the first method if
    // the content is compatible (using or not tags)
    //   plugin->AddDataFile("tag.xml");
    //   plugin->AddDataFile("/alice/data/2008/LHC08c/000057657/raw/Run57657.Merged.RAW.tag.root");

    // Define alien work directory where all files will be copied. Relative to alien $HOME.
    plugin->SetGridWorkingDir(taskname);

    // Declare alien output directory. Relative to working directory.
    plugin->SetGridOutputDir("out"); // In this case will be $HOME/taskname/out

    // Declare the analysis source files names separated by blancs. To be compiled runtime
    // using ACLiC on the worker nodes.

    //DON'T FORGET TO INCLUDE ALL FILES!

    if ( !bMCtruth && !bMCphyssel ) //working with real data sets
    {
        plugin->SetAnalysisSource("AliAnalysisTaskPhi.cxx");
    }
    else
    {
        //working with MC data sets
        plugin->SetAnalysisSource("AliAnalysisTaskPhi.cxx AliAnalysisTaskMCtruePhi.cxx");
    }


    // Declare all libraries (other than the default ones for the framework. These will be
    // loaded by the generated analysis macro. Add all extra files (task .cxx/.h) here.

    //DON'T FORGET TO INCLUDE ALL FILES!

    if ( !bMCtruth && !bMCphyssel ) //working with real data sets
    {
        plugin->SetAdditionalLibs("AliAnalysisTaskPhi.h AliAnalysisTaskPhi.cxx");
    }
    else
    {
        //working with MC data
        plugin->SetAdditionalLibs("AliAnalysisTaskPhi.h AliAnalysisTaskPhi.cxx AliAnalysisTaskMCtruePhi.h AliAnalysisTaskMCtruePhi.cxx");
    }

    // Declare the output file names separated by blancs.
    // (can be like: file.root or file.root@ALICE::Niham::File)
    // To only save certain files, use SetDefaultOutputs(kFALSE), and then
    // SetOutputFiles("list.root other.filename") to choose which files to save
    plugin->SetDefaultOutputs();
    //plugin->SetOutputFiles("list.root");

    // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
    plugin->SetAnalysisMacro(Form("%s.C",taskname));

    // Optionally set maximum number of input files/subjob (default 100, put 0 to ignore)
    plugin->SetSplitMaxInputFileNumber(100);

    // Optionally modify the executable name (default analysis.sh)
    plugin->SetExecutable(Form("%s.sh",taskname));

    // set number of test files to use in "test" mode
    plugin->SetNtestFiles(10);

    // Optionally resubmit threshold.
    plugin->SetMasterResubmitThreshold(90);

    // Optionally set time to live (default 30000 sec)
    plugin->SetTTL(30000);

    // Optionally set input format (default xml-single)
    plugin->SetInputFormat("xml-single");

    // Optionally modify the name of the generated JDL (default analysis.jdl)
    plugin->SetJDLName(Form("%s.jdl",taskname));

    // Optionally modify job price (default 1)
    plugin->SetPrice(1);

    // Optionally modify split mode (default 'se')
    plugin->SetSplitMode("se");
    
    //----------------------------------------------------------
    //---      PROOF MODE SPECIFIC SETTINGS         ------------
    //----------------------------------------------------------
    // Proof cluster
    plugin->SetProofCluster(proofcluster);
    // Dataset to be used
    plugin->SetProofDataSet(proofdataset);
    // May need to reset proof. Supported modes: 0-no reset, 1-soft, 2-hard
    plugin->SetProofReset(0);
    // May limit number of workers
    plugin->SetNproofWorkers(0);
    // May limit the number of workers per slave
    plugin->SetNproofWorkersPerSlave(0);
    // May use a specific version of root installed in proof
    //plugin->SetRootVersionForProof("current");
    // May set the aliroot mode. Check http://aaf.cern.ch/node/83
    plugin->SetAliRootMode("default"); // Loads AF libs by default
    // May request ClearPackages (individual ClearPackage not supported)
    plugin->SetClearPackages(kFALSE);
    // Plugin test mode works only providing a file containing test file locations, used in "local" mode also
    plugin->SetFileForTestMode("files.txt"); // file should contain path name to a local directory containg *ESDs.root etc
    // Request connection to alien upon connection to grid
    plugin->SetProofConnectGrid(kFALSE);

    return plugin;
}

